package cn.bonoon.kernel.io.devices;

import java.io.File;

import javax.servlet.ServletContext;

import org.springframework.util.Assert;

import cn.bonoon.kernel.io.BFile;
import cn.bonoon.kernel.io.FileSize;

/**
 * 本地的存储设备，表示这个位置是通过路径指定的空间，不在服务器本地可访问的目录内
 * 包括临时目录，也使用这个类来定义
 * 
 * @author jackson
 *
 */
public class LocalStorageDevice {
	
	private final static long DEFAULT_STORAGE_MIN_LENGTH = 100 * FileSize.M;
	
	/** 定义的路径，这个路径是未经过处理的原路径，可能是相对路径等。
	 * 必须是本地可以访问的，如本地目录、挂载目录等 */
	private final String sourcePath;//upload/pic2
	
	/** 使用本地的设备的，一般情况下，小于100M就不再存储文件了 */
	private final FileSize minFreeSpace;
	
	private ServletContext servletContext;
	
	private File root;
	
	private final static String PRIFIX = "file:";
	
	
	
	public LocalStorageDevice(String sourcePath, long size){
		Assert.hasText(sourcePath, "必须定义存储设备的存储路径！");
		this.sourcePath = sourcePath;
		this.minFreeSpace = FileSize.valueOf(size > 0 ? size : DEFAULT_STORAGE_MIN_LENGTH);
	}
	
	public LocalStorageDevice(String sourcePath){
		this(sourcePath, DEFAULT_STORAGE_MIN_LENGTH);
	}
	
	public LocalStorageDevice init(ServletContext servletContext){
		this.servletContext = servletContext;
		
		if(sourcePath.startsWith(PRIFIX)){
			root = new File(sourcePath.substring(PRIFIX.length()));
		}else{
			root = new File(servletContext.getRealPath(sourcePath));
		}
		
		if(!root.isDirectory()){
			root.mkdirs();
		}
		
		return this;
	}
	
	public File open(BFile file){
		String fp = file.getFilepath();
		if(fp.startsWith(sourcePath)){
			/*
			 * 路径里已经包括指定的根目录(rootDirectory)，所以
			 * 不需要再进行处理，表示路径为直接指定
			 */
			return new File(servletContext.getRealPath(fp)) ;
		}
		
		return new File(root, fp);
	}
	
	/** 这个设备是否有足够使用的空间 */
	public boolean checkFreeSpace(long needSize){
		if(!root.isDirectory()) root.mkdirs();//如果目录不存在是获取不到空间的，项目启动的时候会自己创建目录，如果启动之后再删除了目录就不会再创建了

		long free = root.getUsableSpace();//.getFreeSpace();
		return (free > minFreeSpace.size()) && (free > needSize);
	}
	
	public String getSourcePath() {
		return sourcePath;
	}
}
